home *** CD-ROM | disk | FTP | other *** search
/ Shareware Grab Bag / Shareware Grab Bag.iso / 007 / x68000.arc / SOURCE.ARC / CODEGENE.MOD < prev    next >
Encoding:
Modula Implementation  |  1986-03-04  |  34.5 KB  |  1,057 lines

  1. IMPLEMENTATION MODULE CodeGenerator;
  2. (* Uses information supplied by Parser, OperationCodes, *)
  3. (* and SyntaxAnalyzer to produce the object code.       *)
  4.  
  5.    FROM Strings IMPORT
  6.       Length, CompareStr;
  7.  
  8.    FROM SymbolTable IMPORT
  9.       FillSymTab, ReadSymTab;
  10.  
  11.    FROM Parser IMPORT
  12.       TOKEN, OPERAND, OpLoc, SrcLoc, DestLoc;
  13.  
  14.    FROM LongNumbers IMPORT
  15.       LONG, LongAdd, LongSub, LongInc, LongDec, 
  16.       LongClear, CardToLong, LongToCard, LongToInt,
  17.       LongCompare, AddrBoundW, AddrBoundL;
  18.  
  19.    FROM OperationCodes IMPORT
  20.       ModeTypeA, ModeTypeB, ModeA, ModeB, Instructions;
  21.  
  22.    FROM ErrorX68 IMPORT
  23.       ErrorType, Error;
  24.  
  25.    FROM SyntaxAnalyzer IMPORT
  26.       SizeType, OpConfig, OpMode, Xtype, 
  27.       GetValue, GetSize, GetInstModeSize, GetOperand, GetMultReg;
  28.  
  29.  
  30.    CONST
  31.       JMP = {14, 11, 10, 9, 7, 6};
  32.       JSR = {14, 11, 10, 9, 7};
  33.       RTE = {14, 11, 10, 9, 6, 5, 4, 1, 0};
  34.       RTR = {14, 11, 10, 9, 6, 5, 4, 2, 1, 0};
  35.       RTS = {14, 11, 10, 9, 6, 5, 4, 2, 0};
  36.       TRAPV = {14, 11, 10, 9, 6, 5, 4, 2, 1};
  37.       STOP = {14, 11, 10, 9, 6, 5, 4, 1};
  38.       LINK = {14, 11, 10, 9, 6, 4};
  39.       SWAP = {14, 11, 6};
  40.       UNLK = {14, 11, 10, 9, 6, 4, 3};
  41.       Quote = 47C;
  42.  
  43.  
  44.    VAR
  45.    (*---     
  46.       (* Defined in DEFINITION MODULE *)
  47.       LZero, AddrCnt : LONG;
  48.       Pass2 : BOOLEAN;                 
  49.                                        ---*)
  50.       AddrAdv : LONG;
  51.       TempL : LONG;     (* Temporary variables *)
  52.       TempI : INTEGER;
  53.       TempC : CARDINAL;
  54.       BrValue : LONG;   (* Used to calculate relative branches *)
  55.       RevBr : BOOLEAN;
  56.       Quick : BOOLEAN;   (* Used by MergeModes *)
  57.       Size : SizeType;       (* size for OpCode *)  
  58.       InstSize : CARDINAL;
  59.       AddrModeA : ModeA;     (* Addressing modes for this instruction *)
  60.       AddrModeB : ModeB;     (*               ditto                   *)
  61.       Op : BITSET;           (* Raw bit pattern for OpCode *)
  62.       Src, Dest : OpConfig;
  63.    
  64.  
  65.  
  66.  
  67.    PROCEDURE BuildSymTable (VAR AddrCnt : LONG;
  68.                             Label, OpCode : TOKEN; SrcOp, DestOp : OPERAND);
  69.    (* Builds symbol table from symbolic information of Source File *)
  70.  
  71.       VAR
  72.          Value : LONG;
  73.          Full : BOOLEAN;
  74.          PseudoOp : BOOLEAN;
  75.  
  76.       BEGIN
  77.          Value := LZero;
  78.          AddrAdv := LZero;
  79.          InstSize := 0;
  80.          PseudoOp := FALSE;
  81.          Size := S0;
  82.  
  83.          IF Length (OpCode) = 0 THEN
  84.             RETURN;   (* Nothing added to symbol table, AddrCnt not changed *)
  85.          END;
  86.  
  87.          GetSize (OpCode, Size);
  88.   
  89.          IF CompareStr (OpCode, "ORG") = 0 THEN
  90.             GetValue (SrcOp, AddrCnt);
  91.             AddrBoundW (AddrCnt);
  92.             Value := AddrCnt;
  93.             PseudoOp := TRUE;
  94.          ELSIF CompareStr (OpCode, "EQU") = 0 THEN
  95.             GetValue (SrcOp, Value);
  96.             PseudoOp := TRUE;
  97.          ELSIF CompareStr (OpCode, "DC") = 0 THEN
  98.             CASE Size OF
  99.                Word  :  AddrBoundW (AddrCnt);
  100.             |  Long  :  AddrBoundL (AddrCnt);
  101.             |  Byte  :  ;
  102.             END;
  103.  
  104.             IF SrcOp[0] = Quote THEN   (* String Constant *)
  105.                TempC := Length (SrcOp);
  106.                IF TempC > 2 THEN
  107.                   InstSize := TempC - 2;
  108.                END;
  109.             ELSE
  110.                InstSize := ORD (Size);
  111.             END;    
  112.             CardToLong (InstSize, AddrAdv);
  113.             Value := AddrCnt;
  114.             PseudoOp := TRUE;
  115.          ELSIF CompareStr (OpCode, "DS") = 0 THEN
  116.             GetValue (SrcOp, AddrAdv);
  117.             Value := AddrCnt;
  118.             PseudoOp := TRUE;
  119.          ELSIF CompareStr (OpCode, "EVEN") = 0 THEN
  120.             AddrBoundW (AddrCnt);
  121.             Value := AddrCnt;
  122.             PseudoOp := TRUE;
  123.          ELSIF CompareStr (OpCode, "END") = 0 THEN
  124.             PseudoOp := TRUE;
  125.          ELSE
  126.             Value := AddrCnt;
  127.          END;
  128.  
  129.          IF Length (Label) # 0 THEN
  130.             FillSymTab (Label, Value, Full);
  131.             IF Full THEN
  132.                Error (0, SymFull);
  133.             END;
  134.          END;
  135.  
  136.          IF NOT PseudoOp THEN
  137.             Instructions (OpCode, OpLoc, Op, AddrModeA, AddrModeB);       
  138.  
  139.             AddrBoundW (AddrCnt);
  140.             Src.Loc := SrcLoc;   Dest.Loc := DestLoc;
  141.             GetOperand (SrcOp, Src);
  142.             GetOperand (DestOp, Dest);
  143.             InstSize := 2;   (* minimum size of instruction *)
  144.  
  145.             IF Brnch IN AddrModeA THEN
  146.                IF Size # Byte THEN
  147.                   INC (InstSize, 2);
  148.                END;
  149.             ELSIF DecBr IN AddrModeA THEN
  150.                INC (InstSize, 2);
  151.             ELSE   
  152.                IF (Op = JMP) OR (Op = JSR) THEN   (* Allows for 'JMP.S' *)
  153.                   IF (Size = Byte) AND (Src.Mode = AbsL) THEN
  154.                      Src.Mode := AbsW;
  155.                   END;
  156.                END;
  157.  
  158.                TempC := GetInstModeSize (Src.Mode, Size, InstSize);
  159.                TempC := GetInstModeSize (Dest.Mode, Size, InstSize);
  160.             END;
  161.  
  162.             IF (Src.Mode = Imm) AND 
  163.              ((Data911 IN AddrModeA) OR (Data03 IN AddrModeA) OR
  164.               (Data07 IN AddrModeA) OR (CntR911 IN AddrModeA)) THEN
  165.                (* Quick instruction *)
  166.                InstSize := 2;
  167.             END;
  168.             CardToLong (InstSize, AddrAdv);   
  169.          END;
  170.       END BuildSymTable;
  171.  
  172.  
  173.  
  174.  
  175.    PROCEDURE OperExt (VAR EA : OpConfig);
  176.    (* Calculate Operand Extension word, and check range of Operands *)
  177.  
  178.       VAR
  179.          GoodInt : BOOLEAN;
  180.          Xext : BITSET;
  181.  
  182.       BEGIN
  183.          GoodInt := LongToInt (EA.Value, TempI);
  184.  
  185.          CASE EA.Mode OF
  186.             AbsL     :  ;   (* No range checking needed *)
  187.          |  AbsW     :  IF NOT GoodInt THEN
  188.                            Error (EA.Loc, SizeErr);
  189.                         END;
  190.          |  ARDisp,  
  191.             PCDisp   :  IF NOT GoodInt THEN
  192.                            Error (EA.Loc, SizeErr);
  193.                         END;
  194.          |  ARDisX,
  195.             PCDisX   :  IF (TempI < -128) OR (TempI > 127) THEN
  196.                            Error (EA.Loc, SizeErr);
  197.                         END;
  198.                         Xext := BITSET (EA.Xn * 4096);
  199.                         IF EA.X = Areg THEN
  200.                            Xext := Xext + {15};
  201.                         END;
  202.                         IF EA.Xsize = Long THEN
  203.                            Xext := Xext + {11};
  204.                         END;
  205.                         CardToLong (CARDINAL (Xext), TempL);
  206.                         EA.Value[3] := TempL[3];
  207.                         EA.Value[4] := TempL[4];
  208.          |  Imm      :  IF Size = Long THEN
  209.                            (* No range check needed *)
  210.                         ELSE
  211.                            IF GoodInt THEN
  212.                               IF Size = Byte THEN
  213.                                  IF (TempI < -128) OR (TempI > 127) THEN
  214.                                     Error (EA.Loc, SizeErr);
  215.                                  END;
  216.                               END;
  217.                            ELSE
  218.                               Error (EA.Loc, SizeErr);
  219.                            END;
  220.                         END;
  221.          ELSE
  222.             (* No Action *)
  223.          END;
  224.       END OperExt;
  225.  
  226.  
  227.  
  228.    PROCEDURE EffAdr (VAR EA : OpConfig; Bad : BITSET);
  229.    (* adds effective address field to Op (BITSET representing opcode) *)
  230.  
  231.       VAR
  232.          M : CARDINAL;
  233.  
  234.       BEGIN
  235.          M := ORD (EA.Mode);
  236.  
  237.          IF M IN Bad THEN
  238.             Error (EA.Loc, ModeErr);
  239.             RETURN;
  240.          ELSIF M > 11 THEN
  241.             RETURN;
  242.          ELSIF M < 7 THEN
  243.             Op := Op + BITSET (M * 8) + BITSET (EA.Rn);
  244.          ELSE   (*    7  <=  M  <=  11   *)
  245.             Op := Op + {5, 4, 3} + BITSET (M - 7);
  246.          END;
  247.  
  248.          OperExt (EA);
  249.       END EffAdr;
  250.  
  251.  
  252.  
  253.    CONST
  254.       (* BITSETs of the modes MISSING from effective address modes  *)
  255.        ea = {};                 (* Effective addressing - all modes *)
  256.       dea = {1};                (* Data effective addressing        *)
  257.       mea = {1, 0};             (* Memory effective addressing      *)
  258.       cea = {11, 4, 3, 1, 0};   (* Control effective addressing     *)
  259.       aea = {11, 10, 9};        (* Alterable effective addressing   *)
  260.       xxx = {15, 14, 13};       (* extra modes: CCR/SR/USP          *)
  261.       (* 2 "AND" masks to turn off switch bits for shift/rotate *)
  262.       Off910 = {15, 14, 13, 12, 11, 8, 7, 6, 5, 4, 3, 2, 1, 0};
  263.       Off34 = {15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 2, 1, 0};
  264.  
  265.  
  266.    PROCEDURE MergeModes1 (VAR SrcOp, DestOp : OPERAND;
  267.                           VAR ObjOp, ObjSrc, ObjDest : LONG;
  268.                           VAR nO,    nS,     nD      : CARDINAL);
  269.    (*  Uses information from Instructions & GetOperand (among others)  *)
  270.    (*  to complete calculation of Object Code.                         *)
  271.    (*  Op, AddrModeA, AddrModeB, Size, and Src & Dest records are all  *)
  272.    (*  Global variables imported from the SyntaxAnalyzer MODULE.       *)
  273.  
  274.       BEGIN
  275.          Quick := FALSE;
  276.  
  277.          (* Check for 5 special cases first *)
  278.  
  279.          IF (Op = RTE) OR (Op = RTR) OR (Op = RTS) OR (Op = TRAPV) THEN
  280.             IF Src.Mode # Null THEN
  281.                Error (SrcLoc, OperErr);
  282.             END;
  283.          END;
  284.  
  285.          IF Op = STOP THEN
  286.             IF (Src.Mode # Imm) OR (Dest.Mode # Null) THEN
  287.                Error (SrcLoc, OperErr);
  288.             END;
  289.          END;
  290.  
  291.          IF Op = LINK THEN
  292.             Op := Op + BITSET (Src.Rn);
  293.             IF (Src.Mode # ARDir) OR (Dest.Mode # Imm) THEN
  294.                Error (SrcLoc, ModeErr);
  295.             END;
  296.          END;
  297.  
  298.          IF Op = SWAP THEN
  299.             IF EA05f IN AddrModeB THEN
  300.                (* Ignore, this is PEA instruction! *)
  301.             ELSE
  302.                Op := Op + BITSET (Src.Rn);
  303.                IF (Src.Mode # DReg) OR (Dest.Mode # Null) THEN
  304.                   Error (SrcLoc, OperErr);
  305.                END;
  306.             END;
  307.          END;
  308.  
  309.          IF Op = UNLK THEN
  310.             Op := Op + BITSET (Src.Rn);
  311.             IF (Src.Mode # ARDir) OR (Dest.Mode # Null) THEN
  312.                Error (SrcLoc, OperErr);
  313.             END;
  314.          END;
  315.  
  316.          (* Now do generalized address modes *)
  317.  
  318.          IF (Ry02 IN AddrModeA) AND (Rx911 IN AddrModeA) THEN
  319.             Op := Op + BITSET (Src.Rn) + BITSET (Dest.Rn * 512);
  320.             (* Now do some error checking! *)
  321.             IF RegMem3 IN AddrModeA THEN
  322.                IF Src.Mode = DReg THEN
  323.                   IF Dest.Mode # DReg THEN
  324.                      Error (DestLoc, ModeErr);
  325.                   END;
  326.                ELSIF Src.Mode = ARPre THEN
  327.                   Op := Op + {3};
  328.                   IF Dest.Mode # ARPre THEN
  329.                      Error (DestLoc, ModeErr);
  330.                   END;
  331.                ELSE
  332.                   Error (SrcLoc, OperErr);
  333.                END;
  334.             ELSE
  335.                IF Src.Mode = ARPost THEN
  336.                   IF Dest.Mode # ARPost THEN
  337.                      Error (DestLoc, ModeErr);
  338.                   END;
  339.                ELSE
  340.                   Error (SrcLoc, OperErr);
  341.                END;
  342.             END;
  343.          END;
  344.  
  345.          IF Data911 IN AddrModeA THEN
  346.             Quick := TRUE;
  347.             IF Src.Mode = Imm THEN
  348.                IF LongToInt (Src.Value, TempI) 
  349.                 AND (TempI > 0)
  350.                  AND (TempI <= 8) THEN
  351.                   IF TempI < 8 THEN   (* Data of 8 is coded as 000 *)
  352.                      Op := Op + BITSET (TempI * 512);
  353.                   END;
  354.                ELSE
  355.                   Error (SrcLoc, SizeErr);
  356.                END;
  357.             ELSE
  358.                Error (SrcLoc, OperErr);
  359.             END;
  360.          END;
  361.  
  362.          IF CntR911 IN AddrModeA THEN
  363.             (* Only Shift/Rotate use this *)
  364.             IF Dest.Mode = DReg THEN
  365.                Op := (Op * Off910) + BITSET (Dest.Rn);
  366.                CASE Size OF
  367.                   Byte : ;
  368.                |  Word : Op := Op + {6};
  369.                |  Long : Op := Op + {7};
  370.                END;
  371.                IF Src.Mode = DReg THEN
  372.                   Op := Op + {5} + BITSET (Src.Rn * 512);               
  373.                ELSIF Src.Mode = Imm THEN
  374.                   Quick := TRUE; 
  375.                   (* Range Check *)
  376.                   IF LongToInt (Src.Value, TempI) 
  377.                    AND (TempI > 0)
  378.                     AND (TempI <= 8) THEN
  379.                      IF TempI < 8 THEN   (* Data of 8 is coded as 000 *)
  380.                         Op := Op + BITSET (TempI * 512);
  381.                      END;
  382.                   ELSE
  383.                      Error (SrcLoc, SizeErr);
  384.                   END;
  385.                ELSE
  386.                   Error (SrcLoc, OperErr);
  387.                END;                    
  388.             ELSIF Dest.Mode = Null THEN
  389.                Op := (Op * Off34) + {7, 6};
  390.                EffAdr (Src, (mea + aea));
  391.             ELSE
  392.                Error (SrcLoc, OperErr);
  393.             END;
  394.          END;
  395.       END MergeModes1;
  396.  
  397.  
  398.  
  399.    PROCEDURE MergeModes2 (VAR SrcOp, DestOp : OPERAND;
  400.                           VAR ObjOp, ObjSrc, ObjDest : LONG;
  401.                           VAR nO,    nS,     nD      : CARDINAL);
  402.  
  403.       BEGIN
  404.          IF Data03 IN AddrModeA THEN
  405.             Quick := TRUE;
  406.             IF Src.Mode = Imm THEN
  407.                IF LongToInt (Src.Value, TempI)
  408.                 AND (TempI >= 0)
  409.                  AND (TempI < 16) THEN
  410.                   Op := Op + BITSET (TempI);
  411.                ELSE
  412.                   Error (SrcLoc, SizeErr);
  413.                END;
  414.             ELSE
  415.                Error (SrcLoc, OperErr);
  416.             END;
  417.          END;
  418.  
  419.          IF Data07 IN AddrModeA THEN
  420.             Quick := TRUE;
  421.             IF (Src.Mode = Imm) AND (Dest.Mode = DReg) THEN
  422.                IF LongToInt (Src.Value, TempI) 
  423.                 AND (TempI >= -128) 
  424.                  AND (TempI <= 127) THEN
  425.                   Op := Op + (BITSET (TempI) * {7, 6, 5, 4, 3, 2, 1, 0}) 
  426.                            + BITSET (Dest.Rn * 512);
  427.                ELSE
  428.                   Error (SrcLoc, SizeErr);
  429.                END;
  430.             ELSE
  431.                Error (SrcLoc, OperErr);
  432.             END;
  433.          END;
  434.  
  435.          IF OpM68D IN AddrModeA THEN
  436.             IF Dest.Mode = DReg THEN
  437.                Op := Op + BITSET (Dest.Rn * 512);
  438.                IF (Src.Mode = ARDir) AND (Size = Byte) THEN
  439.                   Error (SrcLoc, SizeErr);
  440.                END;
  441.             ELSE   (* Assume Src.Mode = DReg -- Error trapped elsewhere *)
  442.                Op := Op + BITSET (Src.Rn * 512);
  443.                Op := Op + {8};
  444.             END;
  445.  
  446.             CASE Size OF
  447.                Byte : ;
  448.             |  Word : Op := Op + {6};
  449.             |  Long : Op := Op + {7};
  450.             END;
  451.          END;
  452.  
  453.          IF OpM68A IN AddrModeA THEN
  454.             IF Dest.Mode = ARDir THEN
  455.                Op := Op + BITSET (Dest.Rn * 512);
  456.             ELSE
  457.                Error (DestLoc, ModeErr);
  458.             END;
  459.  
  460.             CASE Size OF
  461.                Byte : Error (OpLoc, SizeErr);
  462.             |  Word : Op := Op + {7, 6};
  463.             |  Long : Op := Op + {8, 7, 6};
  464.             END;
  465.          END;
  466.  
  467.          IF OpM68C IN AddrModeA THEN
  468.             IF Dest.Mode = DReg THEN
  469.                Op := Op + BITSET (Dest.Rn * 512);
  470.             ELSE
  471.                Error (DestLoc, ModeErr);
  472.             END;
  473.             
  474.             CASE Size OF
  475.                Byte : IF Src.Mode = ARDir THEN
  476.                          Error (OpLoc, SizeErr);
  477.                       END;
  478.             |  Word : Op := Op + {6};
  479.             |  Long : Op := Op + {7};
  480.             END;
  481.          END;
  482.  
  483.          IF OpM68X IN AddrModeA THEN
  484.             IF Src.Mode = DReg THEN
  485.                Op := Op + BITSET (Src.Rn * 512);
  486.             ELSE
  487.                Error (SrcLoc, ModeErr);
  488.             END;
  489.  
  490.             CASE Size OF
  491.                Byte : Op := Op + {8};
  492.             |  Word : Op := Op + {8, 6};
  493.             |  Long : Op := Op + {8, 7};
  494.             END;
  495.          END;
  496.  
  497.          IF OpM68S IN AddrModeA THEN
  498.             IF Src.Mode = DReg THEN
  499.                Op := Op + BITSET (Src.Rn);
  500.             ELSE
  501.                Error (SrcLoc, ModeErr);
  502.             END;
  503.  
  504.             CASE Size OF
  505.                Byte : Error (OpLoc, SizeErr);
  506.             |  Word : Op := Op + {7};
  507.             |  Long :   Op := Op + {7, 6};
  508.             END;
  509.          END;
  510.       END MergeModes2;
  511.  
  512.  
  513.  
  514.    PROCEDURE MergeModes3 (VAR SrcOp, DestOp : OPERAND;
  515.                           VAR ObjOp, ObjSrc, ObjDest : LONG;
  516.                           VAR nO,    nS,     nD      : CARDINAL);
  517.  
  518.       BEGIN
  519.          IF OpM68R IN AddrModeA THEN
  520.             IF (Src.Mode = DReg) AND (Dest.Mode = ARDisp) THEN
  521.                CASE Size OF
  522.                   Byte : Error (OpLoc, SizeErr);
  523.                |  Word : Op := Op + {8, 7};
  524.                |  Long : Op := Op + {8, 7, 6};
  525.                END;
  526.                Op := Op + BITSET (Src.Rn * 512) + BITSET (Dest.Rn);
  527.             ELSIF (Src.Mode = ARDisp) AND (Dest.Mode = DReg) THEN
  528.                CASE Size OF
  529.                   Byte : Error (OpLoc, SizeErr);
  530.                |  Word : Op := Op + {8};
  531.                |  Long : Op := Op + {8, 6};
  532.                END;
  533.                Op := Op + BITSET (Src.Rn) + BITSET (Dest.Rn * 512);
  534.             ELSE
  535.                Error (SrcLoc, ModeErr);
  536.             END;
  537.          END;
  538.  
  539.          IF OpM37 IN AddrModeA THEN
  540.             IF (Src.Mode = DReg) AND (Dest.Mode = DReg) THEN
  541.                Op := Op + {6} + BITSET (Src.Rn * 512) + BITSET (Dest.Rn);
  542.             ELSIF (Src.Mode = ARDir) AND (Dest.Mode = ARDir) THEN
  543.                Op := Op + {6, 3} + BITSET (Src.Rn * 512) + BITSET (Dest.Rn);
  544.             ELSIF (Src.Mode = ARDir) AND (Dest.Mode = DReg) THEN
  545.                Op := Op + {7, 3} + BITSET (Dest.Rn * 512) + BITSET (Src.Rn);
  546.             ELSIF (Src.Mode = DReg) AND (Dest.Mode = ARDir) THEN
  547.                Op := Op + {7, 3} + BITSET (Src.Rn * 512) + BITSET (Dest.Rn);
  548.             ELSE
  549.                Error (SrcLoc, ModeErr);
  550.             END;
  551.          END;
  552.  
  553.          IF Bit811 IN AddrModeB THEN
  554.             IF Src.Mode = DReg THEN
  555.                Op := Op + {8} + BITSET (Src.Rn * 512);
  556.             ELSIF Src.Mode = Imm THEN
  557.                Op := Op + {11};
  558.             ELSE
  559.                Error (SrcLoc, ModeErr);
  560.             END;
  561.          END;
  562.  
  563.          IF Size67 IN AddrModeB THEN
  564.             CASE Size OF
  565.                Byte : ;(* No action -- bits already 0's *)
  566.             |  Word : Op := Op + {6};
  567.             |  Long : Op := Op + {7};
  568.             END;
  569.          END;
  570.  
  571.          IF Size6 IN AddrModeB THEN
  572.             CASE Size OF
  573.                Byte : Error (OpLoc, SizeErr);
  574.             |  Word : (* No Action -- BIT is already 0 *)
  575.             |  Long : Op := Op + {6};
  576.             END;
  577.          END;
  578.  
  579.          IF Size1213A IN AddrModeB THEN
  580.             CASE Size OF
  581.                Byte : Op := Op + {12};
  582.             |  Word : Op := Op + {13, 12};
  583.             |  Long : Op := Op + {13};
  584.             END;
  585.          END;
  586.  
  587.          IF Size1213 IN AddrModeB THEN
  588.             Op := Op + BITSET (Dest.Rn * 512);
  589.             CASE Size OF
  590.                Byte : Error (OpLoc, SizeErr);
  591.             |  Word : Op := Op + {13, 12};
  592.             |  Long : Op := Op + {13};
  593.             END;
  594.          END;
  595.  
  596.          IF EA05a IN AddrModeB THEN
  597.             IF (Dest.Mode = DReg) OR (Dest.Mode = ARDir) THEN
  598.                EffAdr (Src, ea);
  599.             ELSE
  600.                Error (DestLoc, ModeErr);
  601.             END;
  602.          END;
  603.  
  604.          IF EA05b IN AddrModeB THEN
  605.             IF Dest.Mode = DReg THEN
  606.                EffAdr (Src, dea);
  607.                Op := Op + BITSET (Dest.Rn * 512);
  608.             ELSE
  609.                Error (DestLoc, ModeErr);
  610.             END;
  611.          END;
  612.       END MergeModes3;
  613.  
  614.  
  615.  
  616.    PROCEDURE MergeModes4 (VAR SrcOp, DestOp : OPERAND;
  617.                           VAR ObjOp, ObjSrc, ObjDest : LONG;
  618.                           VAR nO,    nS,     nD      : CARDINAL);
  619.  
  620.       VAR
  621.          M : CARDINAL;
  622.          i : CARDINAL;
  623.          Ext : BITSET;      (* Bit pattern for instruction extension word *)
  624.          ExtL : LONG;
  625.  
  626.       BEGIN
  627.          ExtL := LZero;
  628.  
  629.          IF EA05c IN AddrModeB THEN
  630.             EffAdr (Dest, {11, 1});
  631.          END;
  632.  
  633.          IF EA05d IN AddrModeB THEN
  634.             EffAdr (Dest, aea);
  635.             IF (Dest.Mode = ARDir) AND (Size = Byte) THEN
  636.                Error (OpLoc, SizeErr);
  637.             END;
  638.          END;
  639.  
  640.          IF EA05e IN AddrModeB THEN
  641.             IF Dest.Mode = Null THEN
  642.                EffAdr (Src, (dea + aea));
  643.             ELSIF (Src.Mode = Imm) OR (Src.Mode = DReg) THEN
  644.                EffAdr (Dest, (dea + aea));
  645.             ELSE
  646.                Error (SrcLoc, ModeErr);
  647.             END;
  648.          END;
  649.  
  650.          IF EA05f IN AddrModeB THEN   (* LEA & PEA / JMP & JSR *)
  651.             EffAdr (Src, cea);
  652.             IF Rx911 IN AddrModeA THEN
  653.                IF Dest.Mode = ARDir THEN
  654.                   Op := Op + BITSET (Dest.Rn * 512);
  655.                ELSE
  656.                   Error (DestLoc, ModeErr);
  657.                END;
  658.             ELSE
  659.                IF Dest.Mode # Null THEN
  660.                   Error (DestLoc, OperErr);
  661.                END;
  662.             END;
  663.          END;
  664.  
  665.          IF EA05x IN AddrModeB THEN
  666.             IF Dest.Mode = DReg THEN
  667.                EffAdr (Src, dea);
  668.             ELSIF Src.Mode = DReg THEN
  669.                EffAdr (Dest, mea + aea);               
  670.             ELSE
  671.                Error (SrcLoc, OperErr);
  672.             END;
  673.          END;
  674.  
  675.          IF EA05y IN AddrModeB THEN
  676.             IF Dest.Mode = DReg THEN
  677.                EffAdr (Src, ea);
  678.                IF (Src.Mode = ARDir) AND (Size = Byte) THEN
  679.                   Error (OpLoc, SizeErr);
  680.                END;
  681.             ELSIF Src.Mode = DReg THEN
  682.                EffAdr (Dest, (mea + aea));               
  683.             ELSE
  684.                Error (SrcLoc, ModeErr);
  685.             END;
  686.          END;
  687.  
  688.          IF EA05z IN AddrModeB THEN
  689.             IF Src.Mode = MultiM THEN
  690.                EffAdr (Dest, (mea + aea + {3}));
  691.                GetMultReg (SrcOp, (Dest.Mode = ARPre), SrcLoc, Ext);
  692.             ELSIF Dest.Mode = MultiM THEN
  693.                EffAdr (Src, (mea + {11, 4}));
  694.                GetMultReg (DestOp, (Src.Mode = ARPre), DestLoc, Ext);
  695.                Op := Op + {10};   (* set direction *)
  696.             ELSE
  697.                Error (SrcLoc, OperErr);
  698.             END;
  699.  
  700.             INC (nO, 4);   (* extension is part of OpCode *)
  701.             INC (InstSize, 2);
  702.             CardToLong (CARDINAL (Ext), ExtL);
  703.          END;
  704.  
  705.          IF EA611 IN AddrModeB THEN
  706.             IF Dest.Mode = CCR THEN
  707.                Op := {14, 10, 7, 6};
  708.                EffAdr (Src, dea);               
  709.             ELSIF Dest.Mode = SR THEN
  710.                Op := {14, 10, 9, 7, 6};
  711.                EffAdr (Src, dea);               
  712.             ELSIF Src.Mode = SR THEN
  713.                Op := {14, 7, 6};
  714.                EffAdr (Dest, dea + aea);               
  715.             ELSIF Dest.Mode = USP THEN
  716.                Op := {14, 11, 10, 9, 6, 5};
  717.                IF Src.Mode = ARDir THEN
  718.                   Op := Op + BITSET (Src.Rn);
  719.                ELSE
  720.                   Error (SrcLoc, ModeErr);
  721.                END;
  722.             ELSIF Src.Mode = USP THEN
  723.                Op := {14, 11, 10, 9, 6, 5, 3};
  724.                IF Dest.Mode = ARDir THEN
  725.                   Op := Op + BITSET (Dest.Rn);
  726.                ELSE
  727.                   Error (DestLoc, ModeErr);
  728.                END;
  729.             ELSE
  730.                EffAdr (Src, (ea + xxx));
  731.                IF (Size = Byte) AND (Src.Mode = ARDir) THEN
  732.                   Error (SrcLoc, SizeErr);
  733.                END;
  734.  
  735.                M := ORD (Dest.Mode);
  736.                IF (M IN (dea + aea)) OR (M > 11) THEN
  737.                   Error (DestLoc, ModeErr);
  738.                ELSIF M < 7 THEN
  739.                   Op := Op + BITSET (M * 64) + BITSET (Dest.Rn * 512);
  740.                ELSE   (*  7  <=  M  <=  11  *)
  741.                   Op := Op + {8, 7, 6} + BITSET ((M - 7) * 512);
  742.                END;
  743.  
  744.                OperExt (Dest);
  745.             END;
  746.          END;
  747.  
  748.          IF (Dest.Mode = CCR) AND (Src.Mode = Imm) THEN
  749.             IF (Size67 IN AddrModeB) 
  750.              AND (EA05e IN AddrModeB) 
  751.               AND (Exten IN AddrModeB) THEN
  752.                IF 10 IN Op THEN   (* NOT ANDI/EORI/ORI *)
  753.                   Error (DestLoc, ModeErr);
  754.                ELSE
  755.                   Op := Op * {15, 14, 13, 12, 11, 10, 9, 8};   (* AND mask *)
  756.                   Op := Op + {5, 4, 3, 2};                     (*  OR mask *)
  757.                END;
  758.             END;
  759.          END;
  760.  
  761.          IF (Dest.Mode = SR) AND (Src.Mode = Imm) THEN
  762.             IF (Size67 IN AddrModeB) 
  763.              AND (EA05e IN AddrModeB) 
  764.               AND (Exten IN AddrModeB) THEN
  765.                IF 10 IN Op THEN   (* NOT ANDI/EORI/ORI *)
  766.                   Error (DestLoc, ModeErr);
  767.                ELSE
  768.                   Op := Op * {15, 14, 13, 12, 11, 10, 9, 8};   (* AND mask *)
  769.                   Op := Op + {6, 5, 4, 3, 2};                  (*  OR mask *)
  770.                END;
  771.             END;
  772.          END;
  773.  
  774.          CardToLong (CARDINAL (Op), ObjOp);
  775.          INC (InstSize, 2);
  776.          INC (nO, 4);
  777.          IF nO > 4 THEN
  778.             FOR i := 1 TO 4 DO   (* move ObjOp -- make room for extension *)
  779.                ObjOp[i + 4] := ObjOp[i];
  780.                ObjOp[i] := ExtL[i];
  781.             END;
  782.          END;
  783.  
  784.          nS := GetInstModeSize (Src.Mode, Size, InstSize);
  785.          ObjSrc := Src.Value;
  786.          nD := GetInstModeSize (Dest.Mode, Size, InstSize);
  787.          ObjDest := Dest.Value;
  788.  
  789.          IF Quick THEN
  790.             InstSize := 2;
  791.             nS := 0;   nD := 0;
  792.          END;
  793.          CardToLong (InstSize, AddrAdv);
  794.    
  795.       END MergeModes4;
  796.  
  797.  
  798.  
  799.    TYPE
  800.       DirType = (None, Org, Equ, DC, DS, Even, End);
  801.  
  802.    PROCEDURE ObjDir (OpCode : TOKEN; SrcOp : OPERAND; Size : SizeType;
  803.                      VAR AddrCnt, ObjOp, ObjSrc, ObjDest : LONG;
  804.                      VAR   nA,      nO,    nS,     nD    : CARDINAL) : DirType;
  805.    (* Generates Object Code for Assembler Directives *)
  806.  
  807.       VAR
  808.          Dir : DirType;
  809.          i, j : CARDINAL;
  810.          LongString : ARRAY [1..20] OF INTEGER;
  811.  
  812.       BEGIN
  813.          AddrAdv := LZero;
  814.  
  815.          IF CompareStr (OpCode, "ORG") = 0 THEN
  816.             GetValue (SrcOp, AddrCnt);
  817.             AddrBoundW (AddrCnt);
  818.             Dir := Org;
  819.          ELSIF CompareStr (OpCode, "EQU") = 0 THEN
  820.             GetValue (SrcOp, ObjSrc);
  821.             nS := 8;
  822.             Dir := Equ;
  823.          ELSIF CompareStr (OpCode, "DC") = 0 THEN
  824.             CASE Size OF
  825.                Word  :  AddrBoundW (AddrCnt);
  826.             |  Long  :  AddrBoundL (AddrCnt);
  827.             |  Byte  :  ;
  828.             END;
  829.             
  830.             IF SrcOp[0] = Quote THEN   (* String constant *)
  831.                TempC := Length (SrcOp);
  832.                IF TempC > 2 THEN
  833.                   InstSize := TempC - 2;   (* Don't count the Quotes *)
  834.                END;
  835.                   
  836.                i := 1;   j := 20;
  837.                WHILE i <= InstSize DO   (* Change from ASCII to LONG *)
  838.                   CardToLong (ORD (SrcOp[i]), TempL);
  839.                   LongString[j] := TempL[2];
  840.                   LongString[j - 1] := TempL[1];
  841.                   INC (i);   DEC (j, 2);
  842.                END;
  843.  
  844.                i := 1;   INC (j);
  845.                WHILE j <= 20 DO   (* Left Justify String *)
  846.                   LongString[i] := LongString[j];
  847.                   INC (i);   INC (j);
  848.                END;
  849.  
  850.                DEC (i);
  851.                WHILE i > 16 DO   (* Transfer 2 bytes to OpCode *)
  852.                   ObjOp[i - 16] := LongString[i];
  853.                   INC (nO);   DEC (i);
  854.                END;
  855.  
  856.                WHILE i > 8 DO   (* Transfer 4 bytes to Source Operand *)
  857.                   ObjSrc[i - 8] := LongString[i];
  858.                   INC (nS);   DEC (i);
  859.                END;
  860.                                              
  861.                WHILE i > 0 DO   (* Transfer 4 bytes to Destination Operand *)
  862.                   ObjDest[i] := LongString[i];
  863.                   INC (nD);   DEC (i);
  864.                END;
  865.  
  866.                IF SrcOp[InstSize + 1] # Quote THEN
  867.                   Error ((SrcLoc + InstSize + 1), OperErr);
  868.                END;
  869.             ELSE   (* not a string constant *)
  870.                GetValue (SrcOp, ObjSrc);
  871.                InstSize := ORD (Size);
  872.                nS := InstSize * 2;
  873.             END;
  874.             CardToLong (InstSize, AddrAdv);
  875.             nA := 6;
  876.             Dir := DC;
  877.          ELSIF CompareStr (OpCode, "DS") = 0 THEN
  878.             GetValue (SrcOp, AddrAdv);
  879.             nA := 6;   nS := 2;   ObjSrc := LZero;
  880.             Dir := DS;
  881.          ELSIF CompareStr (OpCode, "EVEN") = 0 THEN
  882.             AddrBoundW (AddrCnt);
  883.             Dir := Even;
  884.          ELSIF CompareStr (OpCode, "END") = 0 THEN
  885.             nA := 6;
  886.             Dir := End;
  887.          ELSE
  888.             Dir := None;
  889.          END;
  890.  
  891.          RETURN (Dir);
  892.       END ObjDir;
  893.  
  894.  
  895.  
  896.    PROCEDURE AdvAddrCnt (VAR AddrCnt : LONG);
  897.    (* Advances the address counter based on the length of the instruction *)
  898.       BEGIN
  899.          LongAdd (AddrCnt, AddrAdv, AddrCnt);
  900.       END AdvAddrCnt;
  901.  
  902.  
  903.  
  904.    PROCEDURE GetObjectCode (Label, OpCode : TOKEN;
  905.                             SrcOp, DestOp : OPERAND;
  906.                             VAR AddrCnt, ObjOp, ObjSrc, ObjDest : LONG;
  907.                             VAR   nA,      nO,    nS,     nD    : CARDINAL);
  908.    (* Determines the object code for the operation as well as the operands *)
  909.    (* Returns each (up to 3 fields), along with the length of each.        *) 
  910.  
  911.       VAR
  912.          Dummy : BOOLEAN;
  913.          Dir : DirType;
  914.  
  915.       BEGIN
  916.          AddrAdv := LZero;
  917.          InstSize := 0;
  918.          nA := 0;   nO := 0;   nS := 0;   nD := 0;
  919.  
  920.          IF Length (OpCode) = 0 THEN
  921.             (* ensure no code generated *)
  922.             RETURN;
  923.          END;
  924.          
  925.          GetSize (OpCode, Size);
  926.  
  927.          Dir := ObjDir (OpCode, SrcOp, Size,
  928.                         AddrCnt, ObjOp, ObjSrc, ObjDest,
  929.                           nA,      nO,    nS,     nD    );
  930.  
  931.          IF (Length (Label) # 0) AND (Dir # Equ) THEN
  932.          (* Check for phase error *)
  933.             Dummy := ReadSymTab (Label, TempL, Dummy);
  934.             IF LongCompare (TempL, AddrCnt) # 0 THEN
  935.                Error (0, Phase);
  936.             END;
  937.          END;
  938.  
  939.          IF Dir = None THEN   (* Instruction *)
  940.             AddrBoundW (AddrCnt);   
  941.          ELSE
  942.             RETURN;
  943.          END;
  944.  
  945.          Instructions (OpCode, OpLoc, Op, AddrModeA, AddrModeB);       
  946.          Src.Loc := SrcLoc;   Dest.Loc := DestLoc;  
  947.          GetOperand (SrcOp, Src);   (* Src & Dest are RECORDS *)
  948.          GetOperand (DestOp, Dest);
  949.  
  950.          IF DecBr IN AddrModeA THEN   (* Decrement & Branch *)
  951.             IF Src.Mode # DReg THEN
  952.                Error (SrcLoc, ModeErr);
  953.             END;
  954.  
  955.             BrValue := Dest.Value;
  956.             TempL := AddrCnt;
  957.             TempC := 32767;   (* Maximum Branch *)
  958.             LongInc (TempL, 2);   (* move past instruction for Rel Adr Calc *)
  959.  
  960.             IF LongCompare (BrValue, TempL) < 0 THEN
  961.                RevBr := TRUE;
  962.                LongSub (TempL, BrValue, BrValue);
  963.                INC (TempC);   (* can branch 1 farther in reverse *)
  964.             ELSE
  965.                RevBr := FALSE;
  966.                LongSub (BrValue, TempL, BrValue);
  967.             END;
  968.  
  969.             CardToLong (TempC, TempL);   (* Maximum Branch distance *)
  970.  
  971.             IF LongCompare (BrValue, TempL) > 0 THEN
  972.                Error (DestLoc, BraErr);
  973.             END;
  974.             IF RevBr THEN   (* Make Negative *)
  975.                LongSub (LZero, BrValue, BrValue)
  976.             END;
  977.  
  978.             CardToLong (4, AddrAdv);
  979.             nA := 6;   nO := 4;   nS := 4;  
  980.             CardToLong (CARDINAL (Op + BITSET (Src.Rn)), ObjOp);
  981.             ObjSrc := BrValue;
  982.             RETURN;
  983.          END;
  984.  
  985.          IF Brnch IN AddrModeA THEN   (* Branch *)
  986.             BrValue := Src.Value;   (* Destination of Branch *)
  987.             TempL := AddrCnt;
  988.             LongInc (TempL, 2);
  989.  
  990.             IF Size # Byte THEN   (* Byte Size ---> Short Branch *)
  991.                TempC := 32767;   (* Set maximum branch distance *)
  992.             ELSE                  
  993.                TempC := 127;
  994.             END;
  995.  
  996.             CASE LongCompare (BrValue, TempL) OF
  997.                -1 :  (* Reverse Branch *)
  998.                      RevBr := TRUE;
  999.                      INC (TempC);   (* can branch 1 farther in reverse *)
  1000.                      LongSub (TempL, BrValue, BrValue);
  1001.             |  +1 :  (* Forward Branch *)
  1002.                      RevBr := FALSE;
  1003.                      LongSub (BrValue, TempL, BrValue);
  1004.             |   0 :  IF Size = Byte THEN
  1005.                         Error (SrcLoc, BraErr);
  1006.                      END;
  1007.             END;
  1008.          
  1009.             CardToLong (TempC, TempL);
  1010.  
  1011.             IF LongCompare (BrValue, TempL) > 0 THEN
  1012.                Error (SrcLoc, BraErr);
  1013.             END;
  1014.  
  1015.             IF RevBr THEN
  1016.                LongSub (LZero, BrValue, BrValue);   (* Make negative *)
  1017.             END;
  1018.  
  1019.             IF Size # Byte THEN
  1020.                InstSize := 4;
  1021.                nS := 4;
  1022.                ObjSrc := BrValue; 
  1023.             ELSE
  1024.                InstSize := 2;
  1025.                Dummy := LongToInt (BrValue, TempI);
  1026.                Op := Op + (BITSET (TempI) * {7, 6, 5, 4, 3, 2, 1, 0});
  1027.             END;
  1028.  
  1029.             nA := 6;   nO := 4;
  1030.             CardToLong (InstSize, AddrAdv);
  1031.             CardToLong (CARDINAL (Op), ObjOp);
  1032.             RETURN;
  1033.          END;
  1034.  
  1035.          nA := 6;
  1036.          IF (Op = JMP) OR (Op = JSR) THEN   (* Allows for 'JMP.S' *)
  1037.             IF (Size = Byte) AND (Src.Mode = AbsL) THEN
  1038.                Src.Mode := AbsW;
  1039.             END;
  1040.          END;
  1041.  
  1042.          (* Due to implementation restrictions on the size of procedures, *)
  1043.          (* MergeModes on the LogiTech version had to be split into  four *)
  1044.          MergeModes1 (SrcOp, DestOp, ObjOp, ObjSrc, ObjDest, nO, nS, nD);
  1045.          MergeModes2 (SrcOp, DestOp, ObjOp, ObjSrc, ObjDest, nO, nS, nD);
  1046.          MergeModes3 (SrcOp, DestOp, ObjOp, ObjSrc, ObjDest, nO, nS, nD);
  1047.          MergeModes4 (SrcOp, DestOp, ObjOp, ObjSrc, ObjDest, nO, nS, nD);
  1048.       END GetObjectCode;
  1049.  
  1050.  
  1051. BEGIN   (* MODULE Initialization *)
  1052.    LongClear (LZero);   (* Used as a constant *)
  1053.    AddrCnt := LZero;
  1054.    Pass2 := FALSE;
  1055. END CodeGenerator.
  1056.  
  1057.